﻿using System.Text;
using ERP.Common.Middleware;
using ERP.Common.Util;
using ERP.Common.Util.Util.Controller;
using ERP.SYS.BLL;
using ERP.SYS.Config;
using ERP.SYS.Interfaces;
using ERP.WH.Config;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.EntityFrameworkCore;
using Microsoft.IdentityModel.Tokens;

internal class Program
{
    private static void Main(string[] args)
    {
        var builder = WebApplication.CreateBuilder(args);

        // Add jwt
        ConfigureJwt(builder);

        // Add database connnection
        ConfigureDatabase(builder);

        // Add services to the container.
        ConfigureIoc(builder);

        // Add log
        ConfiguraLogging(builder);

        //builder.Services.AddControllers();
        builder.Services.AddControllers()
            .AddApplicationPart(typeof(BaseController<>).Assembly);
        // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
        builder.Services.AddEndpointsApiExplorer();
        builder.Services.AddSwaggerGen();

        var app = builder.Build();

        ConfigureCors(app, builder);

        app.UseRouting();

        app.UseMiddleware<CustomAuthenticationMiddleware>();

        // Configure the HTTP request pipeline.
        if (app.Environment.IsDevelopment())
        {
            app.UseSwagger();
            app.UseSwaggerUI();
        }

        app.UseAuthorization();

        app.MapControllers();

        app.Run();
    }

    private static void ConfiguraLogging(WebApplicationBuilder builder)
    {
        // 氝樓祩暮翹
        builder.Services.AddLogging(loggingBuilder =>
        {
            loggingBuilder.AddConsole(options =>
            {
                  options.LogToStandardErrorThreshold = LogLevel.Information;
              });
        }); ;
    }

    private static void ConfigureJwt(WebApplicationBuilder builder)
    {
        string secretKey = builder.Configuration["Jwt:SecretKey"];
        if (string.IsNullOrEmpty(secretKey))
        {
            throw new InvalidOperationException("JWT SecretKey is not configured.");
        }

        //悵躇埥酗僅祫屾峈 128 弇ㄗ16 跺趼誹ㄘ
        if (secretKey.Length < 16)
        {
            throw new InvalidOperationException("JWT SecretKey must be at least 128 bits (16 characters) long.");
        }

        byte[] keyBytes = Encoding.UTF8.GetBytes(secretKey);
        var securityKey = new SymmetricSecurityKey(keyBytes);

        builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
            .AddJwtBearer(options =>
            {
                options.TokenValidationParameters = new TokenValidationParameters
                {
                    ValidateIssuerSigningKey = true,
                    IssuerSigningKey = securityKey,
                    ValidateIssuer = false,
                    ValidateAudience = false
                };
            });

        // 場宎趙 JwtUtil
        JwtUtil.SECRET_KEY = secretKey;
        JwtUtil.SECRET_KEY_BYTES = keyBytes;
        JwtUtil.SIGNING_CREDENTIALS = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256);
    }

    private static void ConfigureDatabase(WebApplicationBuilder builder)
    {
        ConfigureERPSysDatabase(builder);
        ConfigureERPWHDatabase(builder);
    }

    private static void ConfigureERPSysDatabase(WebApplicationBuilder builder)
    {
        var connectionString = builder.Configuration.GetConnectionString("ERPSysConnection");

        if (connectionString == null)
        {
            throw new InvalidOperationException("Connection string 'ERPSysConnection' not found.");
        }

        builder.Services.AddDbContext<ERPSysDbContext>((serviceProvider, options) =>
        {
            options
                .UseMySql(connectionString, ServerVersion.AutoDetect(connectionString))
                .EnableSensitiveDataLogging();

            // 如果需要，可以在这里获取其他服务
            var logger = serviceProvider.GetService<ILogger<ERPSysDbContext>>();
        });
    }

    private static void ConfigureERPWHDatabase(WebApplicationBuilder builder)
    {
        var connectionString = builder.Configuration.GetConnectionString("ERPWHConnection");

        if (connectionString == null)
        {
            throw new InvalidOperationException("Connection string 'ERPWHConnection' not found.");
        }

        builder.Services.AddDbContext<ERPWHDbContext>((serviceProvider, options) =>
        {
            options
                .UseMySql(connectionString, ServerVersion.AutoDetect(connectionString))
                .EnableSensitiveDataLogging();

            // 如果需要，可以在这里获取其他服务
            var logger = serviceProvider.GetService<ILogger<ERPWHDbContext>>();
        });
    }

    private static void ConfigureIoc(WebApplicationBuilder builder)
    {
        builder.Services.AddSingleton<IUserService, UserServiceImpl>();
        builder.Services.AddSingleton<IRoleService, RoleServiceImpl>();
        builder.Services.AddSingleton<IPermissionService, PermissionServiceImpl>();
        builder.Services.AddSingleton<IMenuService, MenuServiceImpl>();
    }

    private static void ConfigureCors(WebApplication app, WebApplicationBuilder builder)
    {
        app.UseCors(builder =>
        {
            builder.AllowAnyOrigin()
                   .AllowAnyHeader()
                   .AllowAnyMethod()
                   .SetPreflightMaxAge(TimeSpan.FromSeconds(2000000));
        });
    }
}